package com.atguigu.lease.web.admin.service.impl;

import com.atguigu.lease.common.exception.LeaseException;
import com.atguigu.lease.common.result.ResultCodeEnum;
import com.atguigu.lease.model.entity.*;
import com.atguigu.lease.model.enums.ItemType;
import com.atguigu.lease.web.admin.mapper.RoomInfoMapper;
import com.atguigu.lease.web.admin.service.*;
import com.atguigu.lease.web.admin.vo.attr.AttrValueVo;
import com.atguigu.lease.web.admin.vo.graph.GraphVo;
import com.atguigu.lease.web.admin.vo.room.RoomDetailVo;
import com.atguigu.lease.web.admin.vo.room.RoomItemVo;
import com.atguigu.lease.web.admin.vo.room.RoomQueryVo;
import com.atguigu.lease.web.admin.vo.room.RoomSubmitVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author liubo
 * @description 针对表【room_info(房间信息表)】的数据库操作Service实现
 * @createDate 2023-07-24 15:48:00
 */
@Service
public class RoomInfoServiceImpl extends ServiceImpl<RoomInfoMapper, RoomInfo>
        implements RoomInfoService {
    @Autowired
    private ApartmentInfoService apartmentInfoService;
    @Autowired
    private GraphInfoService graphInfoService;
    @Autowired
    private RoomAttrValueService roomAttrValueService;
    @Autowired
    private RoomFacilityServiceImpl roomFacilityService;
    @Autowired
    private RoomLabelService roomLabelService;
    @Autowired
    private RoomPaymentTypeService roomPaymentTypeService;
    @Autowired
    private RoomLeaseTermService roomLeaseTermService;


    @Autowired
    private LeaseAgreementService leaseAgreementService;


    @Autowired
    private FacilityInfoService facilityInfoService;
    @Autowired
    private LabelInfoService labelInfoService;
    @Autowired
    private PaymentTypeService paymentTypeService;
    @Autowired
    private LeaseTermService leaseTermService;

    @Override
    public boolean saveOrUpdateRoomVo(RoomSubmitVo roomSubmitVo) {
        //todo:图片，属性关系，配套关系，标签关系，支付关系，租期关系
        List<GraphVo> graphVoList = roomSubmitVo.getGraphVoList();
        List<Long> attrValueIds = roomSubmitVo.getAttrValueIds();
        List<Long> facilityInfoIds = roomSubmitVo.getFacilityInfoIds();
        List<Long> labelInfoIds = roomSubmitVo.getLabelInfoIds();
        List<Long> paymentTypeIds = roomSubmitVo.getPaymentTypeIds();
        List<Long> leaseTermIds = roomSubmitVo.getLeaseTermIds();


        Long delRoomId = roomSubmitVo.getId();

        if (delRoomId != null) {//先删除
            removeById(delRoomId);
            graphInfoService.remove(new LambdaQueryWrapper<GraphInfo>()
                    .eq(GraphInfo::getItemType, ItemType.ROOM)
                    .eq(GraphInfo::getItemId, delRoomId));
            roomAttrValueService.remove(new LambdaQueryWrapper<RoomAttrValue>()
                    .eq(RoomAttrValue::getRoomId, delRoomId));
            roomFacilityService.remove(new LambdaQueryWrapper<RoomFacility>()
                    .eq(RoomFacility::getRoomId, delRoomId));
            roomLabelService.remove(new LambdaQueryWrapper<RoomLabel>()
                    .eq(RoomLabel::getRoomId, delRoomId));
            roomPaymentTypeService.remove(new LambdaQueryWrapper<RoomPaymentType>()
                    .eq(RoomPaymentType::getRoomId, delRoomId));
            roomLeaseTermService.remove(new LambdaQueryWrapper<RoomLeaseTerm>()
                    .eq(RoomLeaseTerm::getRoomId, delRoomId));
        }

        boolean b = save(roomSubmitVo);

        Long roomId = roomSubmitVo.getId();


        graphInfoService.saveBatch(graphVoList
                .stream()
                .map(graphVo -> new GraphInfo(graphVo.getName(), ItemType.ROOM, roomId, graphVo.getUrl()))
                .collect(Collectors.toList()));
        roomAttrValueService.saveBatch(attrValueIds
                .stream()
                .map(attrValueId -> new RoomAttrValue(roomId, attrValueId))
                .collect(Collectors.toList()));
        roomFacilityService.saveBatch(facilityInfoIds.stream()
                .map(id -> RoomFacility.builder()
                        .facilityId(id)
                        .roomId(roomId).build())
                .collect(Collectors.toList()));
        roomLabelService.saveBatch(labelInfoIds.stream()
                .map(id -> RoomLabel.builder().labelId(id).roomId(roomId).build())
                .collect(Collectors.toList()));
        roomPaymentTypeService.saveBatch(paymentTypeIds
                .stream()
                .map(id -> RoomPaymentType.builder().roomId(roomId).paymentTypeId(id).build())
                .collect(Collectors.toList()));
        roomLeaseTermService.saveBatch(leaseTermIds.stream()
                .map(id -> RoomLeaseTerm.builder().leaseTermId(id).roomId(roomId).build())
                .collect(Collectors.toList()));

        return b;
    }
//    工厂转化为GraphInfo
//    public static GraphInfo of(GraphVo graphVo, ItemType itemType, Long itemId) {
//        GraphInfo graphInfo = new GraphInfo();graphInfo.setName(graphVo.getName());
//        return graphInfo;
//    }


    @Override
    public IPage<RoomItemVo> getPageRoomItemVo(IPage<RoomItemVo> roomItemVoPage, RoomQueryVo queryVo) {
        //todo:图片，属性关系，配套关系，标签关系，支付关系，租期关系
        IPage<RoomItemVo> roomItemVoIPage = baseMapper.selectRoomItemVo(roomItemVoPage, queryVo);
        return roomItemVoIPage;
    }

    @Override
    public RoomDetailVo getRoomDetailById(Long id) {
        //创建返回类型
        RoomDetailVo roomDetailVo = new RoomDetailVo();
        //查找info组装结果
        RoomInfo roomInfo = getById(id);
        BeanUtils.copyProperties(roomInfo, roomDetailVo);

        ApartmentInfo apartmentInfo= apartmentInfoService.getById(roomInfo.getApartmentId());

        List<GraphVo> graphVoList = graphInfoService.list(new LambdaQueryWrapper<GraphInfo>()
                        .eq(GraphInfo::getItemType, ItemType.ROOM)
                        .eq(GraphInfo::getItemId, id))
                .stream()
                .map(graphInfo -> GraphVo.builder()
                        .name(graphInfo.getName())
                        .url(graphInfo.getUrl()).build())
                .toList();
        //自己写的sql完成三表联查
        List<AttrValueVo> attrValueVo = roomAttrValueService.selectAttrvalueVo(id);
        List<FacilityInfo> facilityInfoList = facilityInfoService.listByIds(
                roomFacilityService.list(
                                new LambdaQueryWrapper<RoomFacility>()
                                        .eq(RoomFacility::getRoomId, id))
                        .stream()
                        .map(RoomFacility::getFacilityId)
                        .toList());

        List<LabelInfo> labelInfoList = labelInfoService.listByIds(
                roomLabelService.list(
                        new LambdaQueryWrapper<RoomLabel>()
                                .eq(RoomLabel::getRoomId, id)).stream().map(RoomLabel::getLabelId).toList());

        List<PaymentType> paymentTypeList = paymentTypeService.listByIds(
                roomPaymentTypeService.list(new LambdaQueryWrapper<RoomPaymentType>().eq(RoomPaymentType::getRoomId, id))
                        .stream().map(RoomPaymentType::getPaymentTypeId).toList());

        List<LeaseTerm> leaseTermList = leaseTermService.listByIds(
                roomLeaseTermService.list(new LambdaQueryWrapper<RoomLeaseTerm>().eq(RoomLeaseTerm::getRoomId, id))
                        .stream().map(RoomLeaseTerm::getLeaseTermId).toList());

        roomDetailVo.setApartmentInfo(apartmentInfo);
        roomDetailVo.setGraphVoList(graphVoList);
        roomDetailVo.setAttrValueVoList(attrValueVo);
        roomDetailVo.setFacilityInfoList(facilityInfoList);
        roomDetailVo.setLabelInfoList(labelInfoList);
        roomDetailVo.setPaymentTypeList(paymentTypeList);
        roomDetailVo.setLeaseTermList(leaseTermList);

        return roomDetailVo;
    }


    //根据roomId删除
    @Override
    public boolean removeRoomVo(Long delRoomId) {

        if (leaseAgreementService.getBaseMapper().selectCount(new LambdaQueryWrapper<LeaseAgreement>()
                .eq(LeaseAgreement::getRoomId, delRoomId)
                .in(LeaseAgreement::getStatus, 2, 5, 7)) > 0) {//判断是否有租约
            throw new LeaseException(ResultCodeEnum.ERR_DELETE_ROOM_WITH_LEASE_TERM);
        }
        boolean b = removeById(delRoomId);
        graphInfoService.remove(new LambdaQueryWrapper<GraphInfo>()
                .eq(GraphInfo::getItemType, ItemType.ROOM)
                .eq(GraphInfo::getItemId, delRoomId));
        roomAttrValueService.remove(new LambdaQueryWrapper<RoomAttrValue>()
                .eq(RoomAttrValue::getRoomId, delRoomId));
        roomFacilityService.remove(new LambdaQueryWrapper<RoomFacility>()
                .eq(RoomFacility::getRoomId, delRoomId));
        roomLabelService.remove(new LambdaQueryWrapper<RoomLabel>()
                .eq(RoomLabel::getRoomId, delRoomId));
        roomPaymentTypeService.remove(new LambdaQueryWrapper<RoomPaymentType>()
                .eq(RoomPaymentType::getRoomId, delRoomId));
        roomLeaseTermService.remove(new LambdaQueryWrapper<RoomLeaseTerm>()
                .eq(RoomLeaseTerm::getRoomId, delRoomId));

        return b;
    }
}




